import sys,os,time
import zmq
import json
import logging
import marshal
import inspect
import cPickle
sys.path.append("./")
from utils import *
reload(sys)
sys.setdefaultencoding('utf-8')
ACTION_DICT={}
ACTION_DICT["REST"]={}
ACTION_DICT["REST"]["ACTION_REST_PUT"]="REST_PUT"
ACTION_DICT["REST"]["ACTION_REST_GET"]="REST_GET"
ACTION_DICT["REST"]["ACTION_REST_POST"]="REST_POST"
ACTION_DICT["REST"]["ACTION_REST_DEL"]="REST_DEL"
ACTION_DICT["REST"]["ACTION_REST_ALL"]="REST_ALL"

CONDITION_DICT={}
CONDITION_DICT["VALUE"]={}
CONDITION_DICT["OP"]={}

CONDITION_DICT["VALUE"]["RULE_COUNT"]="RULE_COUNT"
CONDITION_DICT["VALUE"]["REQUEST_DATA_SIZE"]="REQ_DATA_SIZE"
CONDITION_DICT["VALUE"]["REQUEST_DATA_TOTAL"]="REQ_DATA_TOTAL"
CONDITION_DICT["VALUE"]["REQUEST_COUNT"]="REQ_COUNT"
CONDITION_DICT["VALUE"]["CONN_NO"]="CONN_NO"
CONDITION_DICT["VALUE"]["SYS_TIME"]="SYS_TIME"

CONDITION_DICT["OP"]["="]="="
CONDITION_DICT["OP"]["!"]="!"
CONDITION_DICT["OP"]["<"]="<"
CONDITION_DICT["OP"][">"]=">"
CONDITION_DICT["OP"][">="]=">="
CONDITION_DICT["OP"]["<="]="<="

ALLOW=1
DENY=0
logging.basicConfig(format="[%(asctime)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S",level=logging.DEBUG)

class Subject(object):
	"""docstring for Suject"""
	def __init__(self):
		pass
	def add_attr(self,attr_name,attr_value):
		setattr(self,attr_name,attr_value)


class Action(object):
	"""docstring for Action"""
	#actions based on rest API
	"""
	ACTION_REST_PUT="REST_PUT"
	ACTION_REST_GET="REST_GET"
	ACTION_REST_POST="REST_POST"
	ACTION_REST_DEL="REST_DEL"
	ACTION_REST_ALL="REST_ALL"
	"""

	def __init__(self,api_type):
		self.type=api_type
		self.action_list=[]
		for k in ACTION_DICT[self.type]:
			setattr(Action, k, ACTION_DICT[self.type][k])
		self.action_all=[k[1] for k in ACTION_DICT[self.type].items()]
		pass

	def add_action(self,*actions):
		for ac in actions:
			if ac.endswith("ALL"):
				self.action_list=[]
				self.action_list=[k for k in self.action_all if k != ac]
				break
			self.action_list.append(ac)

	def add_not_action(self,*actions):
		if not self.action_list:
			self.action_list=[k for k in self.action_all if not k.endswith("ALL")]
		for ac in actions:
			if ac.endswith("ALL"):
				self.action_list=[]
				break
			self.action_list.remove(ac)

	def remove_action(self,*actions):
		for ac in actions:
			if ac.endswith("ALL"):
				self.action_list=[]
				break
			self.action_list.remove(ac)


	def list_action(self):
		return self.action_list
		
class Condition(object):
	"""docstring for Condition"""
	def __init__(self):
		for l in CONDITION_DICT:
			for k in CONDITION_DICT[l]:
				setattr(Condition, k, CONDITION_DICT[l][k])
		self.cond_dict={}
		self.cond_list=[]

class Policy(object):
	"""docstring for API"""
	def __init__(self,*args):
		self.pid=args[0]
		self.api_type=args[1]
		self.policy_container={}
		self.subject=Subject()
		
		#for k in ACTION_DICT[self.ptype]:
		#	setattr(Action, k, ACTION_DICT[self.ptype][k])
		self.action=Action(self.api_type)

	def add_policy(self):
		print self.subject.__dict__


	class Target(object):
		"""docstring for Target"""
		def __init__(self, arg):
			self.arg = arg
			
	

	class Obligation(object):
		"""docstring for Obligation"""
		ob_print="PRINT"
		def __init__(self, arg):
			self.arg = arg


class UserConsole(object):
	"""docstring for UserConsole"""
	def __init__(self):
		self.context=zmq.Context()
		self.container=self.context.socket(zmq.DEALER)
		self.container.connect("tcp://localhost:5556")
		self.id="root"

	def build_group(self,group_name, guard_ids=None):
		return self.send_msg(TYPE_GROUP_BUILD,group_name,guard_ids)
		
	def remove_group(self,group_name, target_group=None):
		return self.send_msg(TYPE_GROUP_DEL,group_name,target_group)

	def list_group(self):
		return self.send_msg(TYPE_GROUP_LIST)
	
	def add_group_member(self,group_name,guard_ids):
		return self.send_msg(TYPE_GROUP_ADD,group_name,guard_ids)

	def move_guard(self,guard_ids,target_group):
		return self.send_msg(TYPE_GROUP_MOVE,guard_ids,target_group)

	def list_guard(self,group_name=None):
		return self.send_msg(TYPE_GUARD_LIST,group_name)

	def get_guard_info(self,guard_id):
		return self.send_msg(TYPE_GUARD_GET,guard_id)

	def add_policy(self,policies,target_app,target_group=None,target_guard=None):
		return self.send_msg(TYPE_POLICY_ADD,policies,target_app,target_group,target_guard)

	def del_policy(self,policy_id,target_app,target_group=None,target_guard=None):
		return self.send_msg(TYPE_POLICY_DEL,policies,target_app,target_group,target_guard)

	def get_policy_info(self,policy_ids):
		return self.send_msg(TYPE_POLICY_GET,policy_ids)

	def update_controller(self,func):
		code=func.func_code
		code_str=marshal.dumps(code)
		args=inspect.getargspec(func)[0]
		tmp={}
		func_id=func.__name__
		tmp[func_id]={}
		tmp[func_id]["code"]=code_str
		tmp[func_id]["args"]=args
		print tmp
		return tmp

	def send_msg(self,mtype,*args):
		msg={}
		msg[MSG_TYPE]=mtype
		msg[MSG_SENDER]=self.id
		msg[MSG_BODY]={}
		if mtype==TYPE_GROUP_LIST:
			pass
		if mtype==TYPE_GUARD_LIST:
			if args[0] !=None:
				msg[MSG_BODY][MSG_TARGET]=args[0]
			else:
				msg[MSG_BODY][MSG_TARGET]="ALL"
		if mtype==TYPE_GROUP_BUILD:
			msg[MSG_BODY][MSG_TARGET]=args[0]
			if args[1]==None:
				t=[""]
			else:
				if type(args[1])==str:
					t=[args[1]]
				elif type(args[1])==list:
					t=args[1]
				else:
					return False
			msg[MSG_BODY]["member"]=t

		if mtype==TYPE_GROUP_ADD:
			msg[MSG_BODY][MSG_TARGET]=args[0]
			if type(args[1])==str:
				t=[args[1]]
			elif type(args[1])==list:
				t=args[1]
			else:
				return False
			msg[MSG_BODY]["member"]=t

		if mtype==TYPE_GROUP_MOVE:
			if type(args[1])==str:
				msg[MSG_BODY][MSG_TARGET]=[args[0]]
			elif type(args[1])==list:
				msg[MSG_BODY][MSG_TARGET]=args[0]
			if args[1]==None:
				return False
			else:
				t=args[1]
			msg[MSG_BODY]["member"]=t

		if mtype==TYPE_GROUP_DEL:
			msg[MSG_BODY][MSG_FROM]=args[0]
			if args[1]==None:
				t=""
			else:
				t=args[1]
			msg[MSG_BODY][MSG_TO]=t
		if mtype==TYPE_GUARD_GET:
			msg[MSG_BODY][MSG_TARGET]=args[0]
		if mtype in (TYPE_POLICY_ADD,TYPE_POLICY_DEL):
			msg[MSG_BODY]["POLCIY"]=args[0]
			msg[MSG_BODY]["APPID"]=args[1]
			msg[MSG_BODY]["GROUPID"]=args[2]
			msg[MSG_BODY]["GUARDID"]=args[3]

		if mtype in (TYPE_USR_DEBUG,):
			msg[MSG_BODY]={}
	
		self.container.send(json.dumps(msg))
		msg=eval(self.container.recv())
		if msg[MSG_TYPE]==TYEP_REP_OPERS_ERR:
			#print msg
			return False
		#logging.info("Get DEBUG response from controller %s: %s",msg[MSG_SENDER],msg)
		print msg[MSG_BODY]
		return msg[MSG_BODY]

	def send_fake_command(self,mtype,*args):
		msg={}
		msg[MSG_TYPE]=mtype
		msg[MSG_SENDER]="root"
		if mtype in (TYPE_GROUP_LIST,TYPE_GUARD_LIST):
			msg[MSG_BODY]={}
		if mtype in (TYPE_GROUP_BUILD,TYPE_GROUP_ADD,TYPE_GROUP_MOVE):
			msg[MSG_BODY]={}
			msg[MSG_BODY]["name"]=args[0]
			if not args[1]:
				t=[""]
			else:
				t=args[1]
			msg[MSG_BODY]["member"]=t
		print "fake",msg
		return msg

	def my_new(self,msg):
		print "my_new_rule_1"
		pass

	def send_upate(self):
		msg={}
		msg[MSG_TYPE]=TYPE_UPDATE_CONTROL
		msg[MSG_SENDER]="root"
		msg[MSG_BODY]=self.update_controller(self.my_new)
		msg=cPickle.dumps(msg)
		self.container.send(msg)

	def test(self):
		"""
		msg={}
		msg[MSG_TYPE]=TYPE_USR_DEBUG
		msg[MSG_SENDER]="root"
		self.container.send(json.dumps(msg))

		"""
		self.list_group()
		self.list_guard()
		self.build_group("A")
		self.build_group("B")
		self.build_group("C")
		self.list_group()

		guard_ids=self.list_guard(0).keys()
		print "guard",guard_ids
		self.list_guard("A")
		self.add_group_member("A",guard_ids[0:2])
		self.move_guard(guard_ids[0],"B")
		self.remove_group("A","C")
		self.list_group()
		guard_ids=self.list_guard(0).keys()
		self.get_guard_info(guard_ids[0])

		
		"""
		gs=self.send_command(TYPE_GUARD_LIST)["body"].keys()
		gos=self.send_command(TYPE_GROUP_LIST)["body"].keys()
		l1=len(gs)
		l2=len(gos)

		#print self.send_command(TYPE_GROUP_ADD,gos[2],gs[0:4])
		"""
		"""
		print self.send_command(TYPE_GROUP_LIST)
		print self.send_command(TYPE_GROUP_MOVE,gos[0],gs[0:3])
		print self.send_command(TYPE_GROUP_MOVE,gos[2],gs[2:4])
		print self.send_command(TYPE_GROUP_LIST)
		print self.send_command(TYPE_GROUP_DEL,"3","2")
		print self.send_command(TYPE_GROUP_LIST)
		print self.send_command(TYPE_GUARD_LIST)["body"].keys()
		"""
		"""
		print self.send_command(TYPE_GROUP_LIST)
		print self.send_command(TYPE_GROUP_BUILD,"1",None)
		print self.send_command(TYPE_GROUP_BUILD,"2",None)
		print self.send_command(TYPE_GROUP_BUILD,"3",None)
		print self.send_command(TYPE_GROUP_LIST)
		print self.send_command(TYPE_GROUP_MOVE,"2",['4c14bbf032', '4b4114d032'])
		"""

if __name__ == '__main__':
	#a=API.Attr("test")
	"""
	p=Policy("aaa","REST")
	p.subject.name="111"
	p.subject.age=1
	p.subject.time=str(time.time())[2:3]
	p.subject.add_attr("123","123")
	p.action.add_action(Action.ACTION_REST_PUT)
	#p.action.remove_action(Action.ACTION_REST_PUT)
	print p.action.action_list
	c=Condition()
	print dir(c)
	"""
	#p.condition.add_cond(Condition.SYS_TIME,"=",10,"ALLOW",)
	#p.condition.add_str_cond("IF SYS_TIME > 10:PRINT;ALLOW")
	#p.add_condition()
	u=UserConsole()
	u.test()
			
		